using Gee;
using Gtk;

namespace Ribbons {

	/** Popup gallery. */
	public class GalleryPopupWindow : Window {

		private const int MAX_HEIGHT = 200;
		private const int SCROLLBAR_SIZE = 20;

		private Gee.List<Tile> _tiles;
		private Gee.Map<Tile, Tile> _mapping;
		private uint _rows;
		private uint _columns;
		private Tile _selected_tile;

		private ScrolledWindow _internal_window;
		private Table _tile_table;

		/** Returns the underlying gallery. */
		public Gallery underlying_gallery { get; construct; }

		/**
		 * Default constructor.
		 *
		 * @underlying_gallery  The underlying gallery.
		 */
		public GalleryPopupWindow (Gallery underlying_gallery) {
			this.type = WindowType.POPUP;
			this.underlying_gallery = underlying_gallery;
		}

		construct {
			_tiles = new Gee.ArrayList<Tile> ();
			_mapping = new Gee.HashMap<Tile, Tile> ();

			foreach (var tile in this.underlying_gallery.tiles) {
				var copy = tile.copy ();
				copy.show ();
				_tiles.add (copy);

				if (tile == this.underlying_gallery.selected_tile) {
					copy.selected = true;
					_selected_tile = tile;
				}

				_mapping[copy] = tile;
			}

			int width = this.underlying_gallery.allocation.width;

			_columns = (uint) (width / this.underlying_gallery.tile_width);
			_rows = (uint) Math.ceil ((double) _tiles.size / _columns);

			_tile_table = new Table (_rows, _columns, true);
			_tile_table.show ();
			_tile_table.height_request = (int) _rows * this.underlying_gallery.tile_height;
			_tile_table.width_request = (int) _columns * this.underlying_gallery.tile_width;

			var vp = new Viewport (null, null);
			vp.show ();
			vp.add (_tile_table);

			_internal_window = new ScrolledWindow (null, null);
			_internal_window.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
			_internal_window.show ();
			_internal_window.add (vp);
			_internal_window.height_request = int.min (_tile_table.height_request, MAX_HEIGHT) + SCROLLBAR_SIZE;
			_internal_window.width_request = _tile_table.width_request + SCROLLBAR_SIZE;

			uint x = 0;
			uint y = 0;
			foreach (var tile in _tiles) {
				var box = new ExtraEventBox ();
				box.show ();
				box.add_events (Gdk.EventMask.BUTTON_PRESS_MASK
								| Gdk.EventMask.BUTTON_RELEASE_MASK
								| Gdk.EventMask.POINTER_MOTION_MASK);
				box.add (tile);

				_tile_table.attach_defaults (box, x, x + 1, y, y + 1);
				tile.clicked.connect (tile_clicked);

				if (++x == _columns) {
					x = 0;
					++y;
				}
			}

			add (_internal_window);
			this.child.button_press_event.connect (() => {
				return true;
			});
		}

		private void tile_clicked (Tile sender) {
			if (_selected_tile != null) {
				_selected_tile.selected = false;
			}
			_selected_tile = sender;
			_selected_tile.selected = true;
			
			this.underlying_gallery.selected_tile = _mapping[_selected_tile];
			
			hide ();
		}
	}
}

